/*******************************************************************************
* Copyright (c) 2012 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.rap.ui.internal.servlet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.rap.ui.resources.IResource;
import org.eclipse.ui.internal.WorkbenchPlugin;
class ResourceReader {
private static final String ID_RESOURCES = "org.eclipse.rap.ui.resources";
public static List<IResource> readResources() {
DependentResource[] resources = readResourcesFromExtensions();
DependentResource[] sortedResources = sortResources( resources );
return createResourceList( sortedResources );
}
private static DependentResource[] readResourcesFromExtensions() {
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint point = registry.getExtensionPoint( ID_RESOURCES );
IConfigurationElement[] elements = point.getConfigurationElements();
DependentResource[] resources = new DependentResource[ elements.length ];
for( int i = 0; i < elements.length; i++ ) {
try {
IResource resource = ( IResource )elements[ i ].createExecutableExtension( "class" );
String resourceId = elements[ i ].getAttribute( "id" );
IConfigurationElement[] dependsOn = elements[ i ].getChildren( "dependsOn" );
List<String> resourceDependencies = new ArrayList<String>();
for( int j = 0; j < dependsOn.length; j++ ) {
String dependency = dependsOn[ j ].getAttribute( "resourceId" );
resourceDependencies.add( dependency );
}
resources[ i ] = new DependentResource( resource, resourceId, resourceDependencies );
} catch( CoreException ce ) {
WorkbenchPlugin.getDefault().getLog().log( ce.getStatus() );
}
}
return resources;
}
private static DependentResource[] sortResources( DependentResource[] resources ) {
DependentResource[] result = new DependentResource[ resources.length ];
List<String> sortedResourceIds = new ArrayList<String>();
List<DependentResource> deferredResources = new ArrayList<DependentResource>();
int index = 0;
for( int i = 0; i < resources.length; i++ ) {
DependentResource resource = resources[ i ];
if( resource != null ) {
resource.dependencies.removeAll( sortedResourceIds );
boolean checkDeferredResources = false;
if( resource.dependencies.isEmpty() ) {
result[ index++ ] = resource;
sortedResourceIds.add( resource.id );
checkDeferredResources = true;
} else {
deferredResources.add( resource );
}
while( checkDeferredResources ) {
checkDeferredResources = false;
Iterator<DependentResource> iterator = deferredResources.iterator();
while( iterator.hasNext() ) {
DependentResource deferredResource = iterator.next();
deferredResource.dependencies.removeAll( sortedResourceIds );
if( deferredResource.dependencies.isEmpty() ) {
result[ index++ ] = deferredResource;
sortedResourceIds.add( deferredResource.id );
iterator.remove();
checkDeferredResources = true;
}
}
}
}
}
if( deferredResources.size() != 0 ) {
String pluginId = WorkbenchPlugin.getDefault().getBundle().getSymbolicName();
String message = "Dependencies could not be resolved for " + deferredResources;
WorkbenchPlugin.getDefault().getLog().log( new Status( IStatus.ERROR, pluginId, message ) );
}
return result;
}
private static List<IResource> createResourceList( DependentResource[] sortedResources ) {
List<IResource> result = new ArrayList<IResource>();
for( DependentResource dependentResource : sortedResources ) {
result.add( dependentResource.resource );
}
return result;
}
private static final class DependentResource {
public final IResource resource;
public final String id;
public final List<String> dependencies;
public DependentResource( IResource resource, String id, List<String> dependencies ) {
this.resource = resource;
this.id = id;
this.dependencies = dependencies;
}
@Override
public String toString() {
return id != null ? id : resource.getClass().getName();
}
}
}